package com.lzleang.domreader;

import com.lzleang.model.Student;
import org.w3c.dom.*;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.IOException;
import java.util.ArrayList;

public class DOMReader {
    public static void testDomParser() throws ParserConfigurationException, IOException, SAXException {
        //创建一个DOM解析器工厂对象;
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        //通过工厂对象创建DOM解析器
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
        //解析文档
        Document doc = documentBuilder.parse("src/student.xml");//doc 即为树状结构的存储对象,在内存中;

        ArrayList<Student> students = new ArrayList<>();

        //获取节点
        NodeList XMLpersonlist = doc.getElementsByTagName("student");
        //获取遍历节点
        for (int i = 0; i <XMLpersonlist.getLength(); i++) {
            Student student = new Student();
            NamedNodeMap attributes = XMLpersonlist.item(i).getAttributes();
            //遍历该标签的属性
            for(int j=0;j<attributes.getLength();j++){
                if("id".equals(attributes.item(j).getNodeName())){
                    student.setId(Integer.parseInt(attributes.item(j).getNodeValue()));
                }
            }
            //获取student下的所有子节点
            NodeList childNodes = XMLpersonlist.item(i).getChildNodes();
            for(int k=0;k<childNodes.getLength();k++){
                //需要注意的是子节点指的是节点中包含的所有数据，包括换行符。换行符会返回Test的值#test。在实际操作中，可以使用getNodeType函数来返回子节点的类型，从而来跳过换行符。
                if(childNodes.item(k).getNodeType()== Node.ELEMENT_NODE){
                     if("name".equals(childNodes.item(k).getNodeName())){
                         student.setName(childNodes.item(k).getTextContent());
                     }
                    if("sex".equals(childNodes.item(k).getNodeName())){
                        student.setSex(childNodes.item(k).getTextContent());
                    }
                    if("age".equals(childNodes.item(k).getNodeName())){
                        student.setAge(Integer.parseInt(childNodes.item(k).getTextContent()));
                    }
                }
            }
            students.add(student);
        }
        System.out.println(students);
    }

    //标签属性的相关操作
    public static void attributeHandler() throws ParserConfigurationException, IOException, SAXException, TransformerException {
        //创建一个DOM解析器工厂对象;
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        //通过工厂对象创建DOM解析器
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
        //解析文档
        Document doc = documentBuilder.parse("src/student.xml");//doc 即为树状结构的存储对象,在内存中;



        //找到该标签
        Node student = doc.getElementsByTagName("student").item(0);
        //对已有属性修改
        //获取所有属性的集合,遍历搜索
        NamedNodeMap attributes = student.getAttributes();
        for(int i = 0 ; i < attributes.getLength() ; i++){
            Node item = attributes.item(i);
            if("id".equals(item.getNodeName())){
                item.setNodeValue("99");
            }
        }


        //创建新的属性
        Attr aClass = doc.createAttribute("class");
        aClass.setValue("一年级一班");
        student.getAttributes().setNamedItem(aClass);

        //删除属性
        //找到改标签
        Node student1 = doc.getElementsByTagName("student").item(1);
        NamedNodeMap attributes1 = student1.getAttributes();
        attributes1.removeNamedItem("id");


        //将内存中的数据,写到文件中;
        //下面两句代码只为了得到Transformer对象
        TransformerFactory TransFactory = TransformerFactory.newInstance();
        Transformer former = TransFactory.newTransformer();

//        xmlsource:表示内存中的xml数据(document)
//        outputTarget:将内存输出到什么地方去,关于流的信息
//        former.transform(xmlSource, outputTarget);

        former.transform(new DOMSource(doc), new StreamResult("src/student.xml"));
    }

    //节点操作相关
    public static void updateDomHandler() throws ParserConfigurationException, IOException, SAXException, TransformerException {
        //创建一个DOM解析器工厂对象;
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        //通过工厂对象创建DOM解析器
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
        //解析文档
        Document doc = documentBuilder.parse("src/student.xml");//doc 即为树状结构的存储对象,在内存中;

        //创建一个父标签
        Element student = doc.createElement("student");
        student.setAttribute("id","3");

        //创建一组字标签,并添加内容
        Element name = doc.createElement("name");
        name.setTextContent("陈六");
        Element sex = doc.createElement("sex");
        sex.setTextContent("男");
        Element age = doc.createElement("age");
        age.setTextContent("18");

        //将子节点存入父节点中
        student.appendChild(name);
        student.appendChild(sex);
        student.appendChild(age);
        //将父节点存入根节点中
        doc.getElementsByTagName("root").item(0).appendChild(student);

        //修改节点
        Node name1 = doc.getElementsByTagName("name").item(0);
        name1.setTextContent("王五");

        //删除节点
        //找到节点
        Node student1 = doc.getElementsByTagName("student").item(1);
        //先找到父节点再删除自己
        student1.getParentNode().removeChild(student1);

        //将内存中的数据,写到文件中;
        //下面两句代码只为了得到Transformer对象
        TransformerFactory TransFactory = TransformerFactory.newInstance();
        Transformer former = TransFactory.newTransformer();

//        xmlsource:表示内存中的xml数据(document)
//        outputTarget:将内存输出到什么地方去,关于流的信息
//        former.transform(xmlSource, outputTarget);

        former.transform(new DOMSource(doc), new StreamResult("src/student.xml"));
    }



    public static void main(String[] args) throws IOException, SAXException, ParserConfigurationException, TransformerException {
        updateDomHandler();
    }
}
